package com.herench.bs.transfer;

import org.apache.cxf.endpoint.Client;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.HashMap;
import java.util.Map;

/**
 * 获取患者住院结算信息
 *
 * @author liuxiaohui
 * @date 2019/3/26
 */
public class GetInpSettleInfoTransfer extends AbstractTransfer {
    public GetInpSettleInfoTransfer(String method, Client client, String messageMethod) {
        super(method, client, messageMethod);
    }

    /**
     * 发送：微信前端JSON数据转换为HIS用的XML数据（微信前端==》HIS）
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public String toInvokeMessage(Map<String, Object> params) throws Exception {
        // 患者ID
        String patientId = (String) params.get("patientId");
        // 住院次数
        String visitId = (String) params.get("visitId");


        // 交易ID：his的方法名
        Document document = getTplDoc(getMethod());

        // 将各个入参数设值（入参==》XML）
        Element dataRow = document.getRootElement().element("CommitData").addElement("Data").addElement("DataRow");
        // 患者ID
        dataRow.addAttribute("PATIENT_ID", patientId);
        // 住院次数
        dataRow.addAttribute("VISIT_ID", visitId);


        return document.asXML();
    }

    /**
     * 接收：HIS返回的XML数据并转换为JSON（HIS==》微信前端）
     * @param resMsg
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> toResultMessage(String resMsg) throws Exception {
        Map<String, Object> resMap = new HashMap<>(16);
        Document document = DocumentHelper.parseText(resMsg);

        Element resultInfo = document.getRootElement().element("Result").element("Info");
        String executeStatus = resultInfo.attributeValue("EXECUTE_STATUS");
        String executeMessage = resultInfo.attributeValue("EXECUTE_MESSAGE");

        if (Dialect.getSuccessfulState().equals(executeStatus)) {
            // 获取各个参数的值（出参的树状结构：父==》子）
            Element dataRow = document.getRootElement().element("ReturnData").element("Data").element("DataRow");
            if (dataRow == null) {
                resMap.put("code", "1403");
                resMap.put("message", "调用成功，但是获取的数据为 0 件！");
            } else {
                GetInpSettleInfoInnerMessage innerMessage = new GetInpSettleInfoInnerMessage(dataRow);

                // 患者ID
                resMap.put("patientId", innerMessage.getPatientId());
                // 患者姓名
                resMap.put("name", innerMessage.getName());
                // 身份证号
                resMap.put("idNo", innerMessage.getIdNo());
                // 住院次数
                resMap.put("visitId", innerMessage.getVisitId());
                // 总费用
                resMap.put("costs", innerMessage.getCosts());
                // 应交费用
                resMap.put("charges", innerMessage.getCharges());
                // 实收费用
                resMap.put("payments", innerMessage.getPayments());
                // 医保支付
                resMap.put("insurPay", innerMessage.getInsurPay());
                // 个人自付
                resMap.put("ownPay", innerMessage.getOwnPay());
                // 预交金总额
                resMap.put("totalPrepayment", innerMessage.getTotalPrepayment());
                // 结算状态
                resMap.put("settleStatus", innerMessage.getSettleStatus());
                // 患者确认结算退款方式
                resMap.put("settleRefundType", innerMessage.getSettleRefundType());
                // 患者确认结算退款卡号
                resMap.put("settleRefundCardNo", innerMessage.getSettleRefundCardNo());
                // 患者确认结算退款金额
                resMap.put("settleRefundAmount", innerMessage.getSettleRefundAmount());
                // 患者确认时间
                resMap.put("confirmDateTime", innerMessage.getConfirmDateTime());
                // 患者确认渠道
                resMap.put("confirmOperator", innerMessage.getConfirmOperator());
                // 实际结算退款方式
                resMap.put("factSettleRefundType", innerMessage.getFactSettleRefundType());
                // 实际结算退款卡号
                resMap.put("factSettleRefundCardNo", innerMessage.getFactSettleRefundCardNo());
                // 实际结算退款金额
                resMap.put("factSettleRefundAmount", innerMessage.getFactSettleRefundAmount());
                // 实际结算内部票号
                resMap.put("factSettleRcptNo", innerMessage.getFactSettleRcptNo());
                // 实际结算交易流水号
                resMap.put("factSettleStreamNo", innerMessage.getFactSettleStreamNo());
                // 实际操作时间
                resMap.put("factOperationDateTime", innerMessage.getFactOperationDateTime());
                // 实际退款操作员ID
                resMap.put("factRefundOperatorNo", innerMessage.getFactRefundOperatorNo());
                // 实际退款操作员姓名
                resMap.put("factRefundOperator", innerMessage.getFactRefundOperator());
                // 无法结算退款原因
                resMap.put("noSettleReason", innerMessage.getNoSettleReason());


                // 返回Code
                resMap.put("code", executeStatus);
                // 返回信息
                resMap.put("message", "成功！");
            }
        } else {
            resMap.put("code", executeStatus);
            resMap.put("message", executeMessage);
        }
        return resMap;
    }

    public class GetInpSettleInfoInnerMessage implements InnerMessage{

        /**
         * 患者ID
         */
        private String patientId;
        /**
         * 患者姓名
         */
        private String name;
        /**
         * 身份证号
         */
        private String idNo;
        /**
         * 住院次数
         */
        private String visitId;
        /**
         * 总费用
         */
        private String costs;
        /**
         * 应交费用
         */
        private String charges;
        /**
         * 实收费用
         */
        private String payments;
        /**
         * 医保支付
         */
        private String insurPay;
        /**
         * 个人自付
         */
        private String ownPay;
        /**
         * 预交金总额
         */
        private String totalPrepayment;
        /**
         * 结算状态
         */
        private String settleStatus;
        /**
         * 患者确认结算退款方式
         */
        private String settleRefundType;
        /**
         * 患者确认结算退款卡号
         */
        private String settleRefundCardNo;
        /**
         * 患者确认结算退款金额
         */
        private String settleRefundAmount;
        /**
         * 患者确认时间
         */
        private String confirmDateTime;
        /**
         * 患者确认渠道
         */
        private String confirmOperator;
        /**
         * 实际结算退款方式
         */
        private String factSettleRefundType;
        /**
         * 实际结算退款卡号
         */
        private String factSettleRefundCardNo;
        /**
         * 实际结算退款金额
         */
        private String factSettleRefundAmount;
        /**
         * 实际结算内部票号
         */
        private String factSettleRcptNo;
        /**
         * 实际结算交易流水号
         */
        private String factSettleStreamNo;
        /**
         * 实际操作时间
         */
        private String factOperationDateTime;
        /**
         * 实际退款操作员ID
         */
        private String factRefundOperatorNo;
        /**
         * 实际退款操作员姓名
         */
        private String factRefundOperator;
        /**
         * 无法结算退款原因
         */
        private String noSettleReason;



        public GetInpSettleInfoInnerMessage(Element element) {
            // 患者ID
            this.patientId = element.attributeValue("PATIENT_ID");
            // 患者姓名
            this.name = element.attributeValue("NAME");
            // 身份证号
            this.idNo = element.attributeValue("ID_NO");
            // 住院次数
            this.visitId = element.attributeValue("VISIT_ID");
            // 总费用
            this.costs = element.attributeValue("COSTS");
            // 应交费用
            this.charges = element.attributeValue("CHARGES");
            // 实收费用
            this.payments = element.attributeValue("PAYMENTS");
            // 医保支付
            this.insurPay = element.attributeValue("INSUR_PAY");
            // 个人自付
            this.ownPay = element.attributeValue("OWN_PAY");
            // 预交金总额
            this.totalPrepayment = element.attributeValue("TOTAL_PREPAYMENT");
            // 结算状态
            this.settleStatus = element.attributeValue("SETTLE_STATUS");
            // 患者确认结算退款方式
            this.settleRefundType = element.attributeValue("SETTLE_REFUND_TYPE");
            // 患者确认结算退款卡号
            this.settleRefundCardNo = element.attributeValue("SETTLE_REFUND_CARD_NO");
            // 患者确认结算退款金额
            this.settleRefundAmount = element.attributeValue("SETTLE_REFUND_AMOUNT");
            // 患者确认时间
            this.confirmDateTime = element.attributeValue("CONFIRM_DATE_TIME");
            // 患者确认渠道
            this.confirmOperator = element.attributeValue("CONFIRM_OPERATOR");
            // 实际结算退款方式
            this.factSettleRefundType = element.attributeValue("FACT_SETTLE_REFUND_TYPE");
            // 实际结算退款卡号
            this.factSettleRefundCardNo = element.attributeValue("FACT_SETTLE_REFUND_CARD_NO");
            // 实际结算退款金额
            this.factSettleRefundAmount = element.attributeValue("FACT_SETTLE_REFUND_AMOUNT");
            // 实际结算内部票号
            this.factSettleRcptNo = element.attributeValue("FACT_SETTLE_RCPT_NO");
            // 实际结算交易流水号
            this.factSettleStreamNo = element.attributeValue("FACT_SETTLE_STREAM_NO");
            // 实际操作时间
            this.factOperationDateTime = element.attributeValue("FACT_OPERATION_DATE_TIME");
            // 实际退款操作员ID
            this.factRefundOperatorNo = element.attributeValue("FACT_REFUND_OPERATOR_NO");
            // 实际退款操作员姓名
            this.factRefundOperator = element.attributeValue("FACT_REFUND_OPERATOR");
            // 无法结算退款原因
            this.noSettleReason = element.attributeValue("NO_SETTLE_REASON");


        }


        /**
         * 患者ID
         */
        public String getPatientId() {
            return patientId;
        }
        /**
         * 患者姓名
         */
        public String getName() {
            return name;
        }
        /**
         * 身份证号
         */
        public String getIdNo() {
            return idNo;
        }
        /**
         * 住院次数
         */
        public String getVisitId() {
            return visitId;
        }
        /**
         * 总费用
         */
        public String getCosts() {
            return costs;
        }
        /**
         * 应交费用
         */
        public String getCharges() {
            return charges;
        }
        /**
         * 实收费用
         */
        public String getPayments() {
            return payments;
        }
        /**
         * 医保支付
         */
        public String getInsurPay() {
            return insurPay;
        }
        /**
         * 个人自付
         */
        public String getOwnPay() {
            return ownPay;
        }
        /**
         * 预交金总额
         */
        public String getTotalPrepayment() {
            return totalPrepayment;
        }
        /**
         * 结算状态
         */
        public String getSettleStatus() {
            return settleStatus;
        }
        /**
         * 患者确认结算退款方式
         */
        public String getSettleRefundType() {
            return settleRefundType;
        }
        /**
         * 患者确认结算退款卡号
         */
        public String getSettleRefundCardNo() {
            return settleRefundCardNo;
        }
        /**
         * 患者确认结算退款金额
         */
        public String getSettleRefundAmount() {
            return settleRefundAmount;
        }
        /**
         * 患者确认时间
         */
        public String getConfirmDateTime() {
            return confirmDateTime;
        }
        /**
         * 患者确认渠道
         */
        public String getConfirmOperator() {
            return confirmOperator;
        }
        /**
         * 实际结算退款方式
         */
        public String getFactSettleRefundType() {
            return factSettleRefundType;
        }
        /**
         * 实际结算退款卡号
         */
        public String getFactSettleRefundCardNo() {
            return factSettleRefundCardNo;
        }
        /**
         * 实际结算退款金额
         */
        public String getFactSettleRefundAmount() {
            return factSettleRefundAmount;
        }
        /**
         * 实际结算内部票号
         */
        public String getFactSettleRcptNo() {
            return factSettleRcptNo;
        }
        /**
         * 实际结算交易流水号
         */
        public String getFactSettleStreamNo() {
            return factSettleStreamNo;
        }
        /**
         * 实际操作时间
         */
        public String getFactOperationDateTime() {
            return factOperationDateTime;
        }
        /**
         * 实际退款操作员ID
         */
        public String getFactRefundOperatorNo() {
            return factRefundOperatorNo;
        }
        /**
         * 实际退款操作员姓名
         */
        public String getFactRefundOperator() {
            return factRefundOperator;
        }
        /**
         * 无法结算退款原因
         */
        public String getNoSettleReason() {
            return noSettleReason;
        }


    }
}
